<template>
  <div class="tui-form-item">
    <div v-if="label" class="tui-form-item-label-container" :style="{ width: ensureUnit(labelWidth, 'px') }" ref="labelContainerRef">
      <span :style="{ visibility: required ? 'visible' : 'hidden' }" class="tui-form-item-required">*</span>
      <label :for="formItemId" class="tui-form-item-label-text">
        {{ label }}
      </label>
    </div>
    <div class="tui-form-item-content">
      <slot></slot>
      <div v-if="localErrorMessage" class="tui-form-item-error">{{ localErrorMessage }}</div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { computed, provide, inject, onMounted, ref, watch, nextTick, Ref } from 'vue';
import { ensureUnit } from '../../strings/index';
import { Random } from '../../random'
import { TuiFormItemProps } from './types';

// 使用withDefaults为props设置默认值
const props = withDefaults(defineProps<TuiFormItemProps>(), {
  id: undefined,
  label: '',
  labelWidth: 'auto',
  required: false,
  errorMessage: ''
});

// 计算属性，优先使用用户提供的id，否则自动生成唯一id
const formItemId = computed(() => props.id || `tui-form-item-${Random.chars(8)}`);

// 提供id给子组件（表单控件）- 使用响应式对象而不是静态值
provide('formItemId', formItemId);

// 注入Form组件提供的registerLabel方法，添加类型检查
const registerLabel = inject<(element: HTMLElement, labelWidth?: string | number) => void>('registerLabel', () => {
  console.warn('FormItem: registerLabel method not provided by parent Form component');
});

// 用于存储label容器元素的ref
const labelContainerRef = ref<HTMLElement | null>(null);

// 注入表单验证结果，添加默认值和类型检查
const formErrors = inject<Ref<Record<string, string[]>>>('formErrors', ref<Record<string, string[]>>({}));

// 存储子组件提供的字段名
const fieldName = ref<string>('');

// 提供方法让子组件可以注册字段名，并添加错误处理
provide('registerFieldName', (name: string) => {
  try {
    if (typeof name === 'string') {
      // 如果字段名发生变化，先清除旧字段名的错误信息（如果有）
      if (fieldName.value && fieldName.value !== name && formErrors.value && formErrors.value[fieldName.value]) {
        delete formErrors.value[fieldName.value];
      }
      fieldName.value = name;
    } else {
      console.warn('FormItem: Invalid field name provided, must be a string');
    }
  } catch (error) {
    console.error('FormItem: Error registering field name:', error);
  }
});

// 使用computed替代watch来响应式地计算错误信息
const localErrorMessage = computed(() => {
  try {
    // 优先使用props传入的errorMessage
    if (props.errorMessage) {
      return props.errorMessage;
    }

    // 如果没有自定义错误信息，且有字段名和错误信息，则显示第一个错误
    if (fieldName.value && formErrors.value && formErrors.value[fieldName.value] && formErrors.value[fieldName.value].length > 0) {
      return formErrors.value[fieldName.value][0];
    }

    return '';
  } catch (error) {
    console.error('FormItem: Error calculating error message:', error);
    return '';
  }
});

// 在组件挂载后，如果有label且存在registerLabel方法，则注册标签元素
onMounted(() => {
  registerLabelIfNeeded();
});

// 监听labelWidth和label属性的变化，当任一值变化时重新注册标签元素
watch([() => props.labelWidth, () => props.label], () => {
  // 使用nextTick确保DOM已更新
  nextTick(() => {
    registerLabelIfNeeded();
  });
});

// 封装注册标签元素的逻辑为单独的函数
function registerLabelIfNeeded() {
  try {
    if (props.label && labelContainerRef.value && registerLabel) {
      // 传递元素和对应的labelWidth给registerLabel方法
      registerLabel(labelContainerRef.value, props.labelWidth);
    }
  } catch (error) {
    console.error('FormItem: Error registering label:', error);
  }
}
</script>

<style scoped lang="scss">
.tui-form-item {
  display: flex;
  align-items: center;

  &-label-container {
    flex-shrink: 0;
    display: flex;
    align-items: center;
  }

  &-label-text {
    font-weight: 500;
    line-height: 32px;
    padding-right: 4px;
  }

  &-required {
    color: var(--tui-color-danger, #F56C6C);
    display: inline-block;
    width: 16px;
    text-align: left;
  }

  &-content {
    flex: 1;
    min-width: 0;
    margin-left: 12px;
  }

  &-error {
    color: var(--tui-color-danger, #F56C6C);
    font-size: 12px;
    line-height: 1;
    padding-top: 4px;
  }
}
</style>